#include "dmxinterface.h"
#include "mock_dmxInterface.h"

/** @file mock_dmxInterface.cpp
 *
 * This file holds a mock implementation of monostate class \ref dmxInterface
 * and an helper calss \ref SpyDmxInterface that allow to inspect how the former
 * class was used.
 * The purpose is to store calls with arguments and let test code retrieve
 * this info.
 * This file contains the implementation of all static functions present in
 * real DMX interface and mocked one.
 */

/** this is not the real number of channels, but it's a small value used
 * for test. \ref dmxInterface::startDmxService must be called with this value
 */
#define NUMBER_OF_TEST_CHANNELS     3

/* static data */
bool SpyDmxInterface::m_mockResultForStart = false;
bool DmxInterface::m_dllLoaded = false;
int DmxInterface::m_numOfChannels = NUMBER_OF_TEST_CHANNELS;

QList<double> SpyDmxInterface::m_lightsetValues;

/**
 * @brief mock implementation returns the result set by test SW
 * @return selected result by \ref SpyDmxInterface::setDmxStartResult
 */
bool DmxInterface::startDmxService(int numberOfChannels)
{
   /* make any test fail if the expected number of channels is not passed */
   if (numberOfChannels != NUMBER_OF_TEST_CHANNELS)
   {
      throw QString("Not the correct number of channels");
   }

   /* reset light set list values */
   SpyDmxInterface::reset( numberOfChannels);

   m_dllLoaded = SpyDmxInterface::getDmxStartResult();
   return m_dllLoaded;
}

void DmxInterface::stopDmxService()
{
   m_dllLoaded = false;
}

void DmxInterface::setValueForChannel( double value, int channel)
{
   SpyDmxInterface::setValueAtChannel( value, channel);
}

void DmxInterface::setValueForAllChannels( QList<double> values)
{
   for (int i=0; i < values.length(); i++)
   {
      setValueForChannel( values.at(i), i);
   }
}

void DmxInterface::turnAllChannelsOff()
{
   for (int i=0; i < m_numOfChannels; i++)
   {
      setValueForChannel( 0, i);
   }
}

/* DMX spy class */

SpyDmxInterface::SpyDmxInterface()
{
   m_mockResultForStart = false;
}

void SpyDmxInterface::setDmxStartResult(bool res)
{
   m_mockResultForStart = res;
}

bool SpyDmxInterface::getDmxStartResult()
{
   return m_mockResultForStart;
}

double SpyDmxInterface::getValueAtChannel(int channel)
{
   if (channel >= m_lightsetValues.length())
   {
      throw QString("invalid channel");
   }

   return m_lightsetValues.at(channel);
}

void SpyDmxInterface::setValueAtChannel(double value, int channel)
{
   if (channel >= m_lightsetValues.length())
   {
      throw QString("invalid channel");
   }

   m_lightsetValues[channel] = value;
}

void SpyDmxInterface::reset(int channel)
{
   m_lightsetValues.clear();

   for (int i = 0; i < channel; i++)
   {
      m_lightsetValues << 0.;
   }
}
